package cn.wuyu.baselibrary.utils;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import androidx.annotation.NonNull;

/**
 * 字符串操作工具包
 * Created by zwl on 2016/6/17.
 */
public class StringUtils {

    private final static Pattern emailer = Pattern
            .compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
    private final static Pattern phone = Pattern
            .compile("^((13[0-9])|170|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");

    private final static ThreadLocal<SimpleDateFormat> dateFormater = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    private final static ThreadLocal<SimpleDateFormat> dateFormater2 = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    /**
     * 返回当前系统时间
     */
    public static String getDataTime(String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        return df.format(new Date());
    }

    /**
     * 返回当前系统时间
     */
    public static String getDataTime() {
        return getDataTime("HH:mm");
    }

    /**
     * 毫秒值转换为mm:ss
     */
    public static String timeFormat(long time) {
//        StringBuilder time = new StringBuilder();
//        time.delete(0, time.length());
//        ms /= 1000;
//        int s = ms % 60;
//        int min = ms / 60;
//        if (min < 10) {
//            time.append(0);
//        }
//        time.append(min).append(":");
//        if (s < 10) {
//            time.append(0);
//        }
//        time.append(s);
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        return sdf.format(new Date(time));
    }

    /**
     * 将字符串转位日期类型
     *
     * @return
     */
    public static Date toDate(String sdate) {
        try {
            return dateFormater.get().parse(sdate);
        } catch (ParseException e) {
            return null;
        }
    }


    public static Date getCurrentDate() {
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long currentTimeMillis = System.currentTimeMillis();
        Date currentDate = systemTime2DateTime(currentTimeMillis);
        return currentDate;
    }

    /**
     * 系统时间转化为Date时间
     */
    public static Date systemTime2DateTime(long systemTime) {
        Date date = new Date(systemTime);
        return date;
    }

    /**
     * 判断给定字符串时间是否为今日
     *
     * @param sdate
     * @return boolean
     */
    public static boolean isToday(String sdate) {
        boolean b = false;
        Date time = toDate(sdate);
        Date today = new Date();
        if (time != null) {
            String nowDate = dateFormater2.get().format(today);
            String timeDate = dateFormater2.get().format(time);
            if (nowDate.equals(timeDate)) {
                b = true;
            }
        }
        return b;
    }

    /**
     * 判断给定字符串是否空白串 空白串是指由空格、制表符、回车符、换行符组成的字符串 若输入字符串为null或空字符串，返回true
     */
    public static boolean isEmpty(String input) {
        if (input == null || "".equals(input))
            return true;

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断是不是一个合法的电子邮件地址
     */
    public static boolean isEmail(String email) {
        if (email == null || email.trim().length() == 0)
            return false;
        return emailer.matcher(email).matches();
    }

    /**
     * 判断是不是一个合法的手机号码
     */
    public static boolean isPhone(String phoneNum) {
        if (phoneNum == null || phoneNum.trim().length() == 0)
            return false;
        return phone.matcher(phoneNum).matches();
    }

    /**
     * 字符串转整数
     *
     * @param str
     * @param defValue
     * @return
     */
    public static int toInt(String str, int defValue) {
        try {
            return Integer.parseInt(str);
        } catch (Exception e) {
        }
        return defValue;
    }

    /**
     * 对象转整
     *
     * @param obj
     * @return 转换异常返回 0
     */
    public static int toInt(Object obj) {
        if (obj == null)
            return 0;
        return toInt(obj.toString(), 0);
    }

    /**
     * String转long
     *
     * @param obj
     * @return 转换异常返回 0
     */
    public static long toLong(String obj) {
        try {
            return Long.parseLong(obj);
        } catch (Exception e) {
        }
        return 0;
    }

    /**
     * String转double
     *
     * @param obj
     * @return 转换异常返回 0
     */
    public static double toDouble(String obj) {
        try {
            return Double.parseDouble(obj);
        } catch (Exception e) {
        }
        return 0D;
    }

    /**
     * 字符串转布尔
     *
     * @param b
     * @return 转换异常返回 false
     */
    public static boolean toBool(String b) {
        try {
            return Boolean.parseBoolean(b);
        } catch (Exception e) {
        }
        return false;
    }

    /**
     * 判断一个字符串是不是数字
     */
    public static boolean isNumber(String str) {
        try {
            Integer.parseInt(str);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 获取AppKey
     */
    public static String getMetaValue(Context context, String metaKey) {
        Bundle metaData = null;
        String apiKey = null;
        if (context == null || metaKey == null) {
            return null;
        }
        try {
            ApplicationInfo ai = context.getPackageManager()
                    .getApplicationInfo(context.getPackageName(),
                            PackageManager.GET_META_DATA);
            if (null != ai) {
                metaData = ai.metaData;
            }
            if (null != metaData) {
                apiKey = metaData.getString(metaKey);
            }
        } catch (PackageManager.NameNotFoundException e) {
        }
        return apiKey;
    }

    /**
     * MD5加密
     */
    public static String md5(String string) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(
                    string.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Huh, MD5 should be supported?", e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Huh, UTF-8 should be supported?", e);
        }

        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10)
                hex.append("0");
            hex.append(Integer.toHexString(b & 0xFF));
        }
        return hex.toString();
    }

    /**
     * 将字符串进行反转
     *
     * @param s
     * @return
     */
    public static String reverse(String s) {
        char[] array = s.toCharArray();
        String reverse = "";
        for (int i = array.length - 1; i >= 0; i--)
            reverse += array[i];
        return reverse;
    }

    /**
     * 将字节长度表示单位转化为B，KB，或MB的格式
     * <b>注意</b>，不能表示大于1G的字节长度?
     */
    public static String getSizeStr(long size) {
        DecimalFormat df = new DecimalFormat("#.0");
        double baseKB = 1024.00, baseMB = 1024 * 1024.00;
        String strSize = "";
        if (size < baseKB) {
            strSize = size + "B";

        } else if (size > baseKB && size < baseMB) {
            strSize = df.format(size / baseKB) + "KB";

        } else if (size > baseMB) {
            strSize = df.format(size / baseMB) + "MB";

        }
        return strSize;
    }

    /**
     * KJ加密
     */
    public static String KJencrypt(String str) {
        char[] cstr = str.toCharArray();
        StringBuilder hex = new StringBuilder();
        for (char c : cstr) {
            hex.append((char) (c + 5));
        }
        return hex.toString();
    }

    /**
     * KJ解密
     */
    public static String KJdecipher(String str) {
        char[] cstr = str.toCharArray();
        StringBuilder hex = new StringBuilder();
        for (char c : cstr) {
            hex.append((char) (c - 5));
        }
        return hex.toString();
    }


    public static String systemTime2Date(String beginDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sd = sdf.format(new Date(Long.parseLong(beginDate)));
        return sd;
    }


    /**
     * （检查用户密码输入正确性正则表达式）
     * 至少包含一个数字和字母且长度为6-20,
     */
    public static boolean isPassword(String password) {
        if (password.length() >= 6 && password.length() <= 20) {
            String regex = "^[0-9a-zA-Z]{6,20}$";
            return password.matches(regex);
        }
        return false;

    }

    /**
     * 当前系统时间和某一给定时间距离滴天数
     *
     * @return
     */

    public static int getCurrentDateDistanceOneDate(String date) {
//         Date parse =null;
//         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//         try {
//             parse = sdf.parse(date);
//         } catch (ParseException e) {
//             // TODO Auto-generated catch block
//             e.printStackTrace();
//         }
//         String strDate = sdf.format(parse);
//
//         // 截取当前时间时分秒
//         int strDateY = Integer.parseInt(strDate.substring(0, 4));
//         int strDateM = Integer.parseInt(strDate.substring(5, 7));
//         int strDateD = Integer.parseInt(strDate.substring(8, 10));
//
//
//         Calendar cal = Calendar.getInstance();
//         cal.set(strDateY, strDateM, strDateD, 00, 00, 00);
//         Calendar now = Calendar.getInstance();
//         now.set(Calendar.HOUR_OF_DAY, 0);
//         now.set(Calendar.MINUTE, 0);
//         now.set(Calendar.SECOND, 0);
//         long intervalMilli = now.getTimeInMillis() - cal.getTimeInMillis();
//         int days = (int) (intervalMilli / (24 * 60 * 60 * 1000));


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//         String dstr="2016-11-20";
        Date dates = null;
        try {
            dates = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        long s1 = dates.getTime();//将时间转为毫秒
        long s2 = System.currentTimeMillis();//得到当前的毫秒
        int days = (int) ((s2 - s1) / 1000 / 60 / 60 / 24);
        return days;
    }

    /**
     * 判断时间是否在时间段内  一段时期
     *
     * @param strDateBegin 开始时间 2015-05-00
     * @param strDateEnd   结束时间 2015-05-00
     * @return
     */
    public static boolean isCurrentTimeInDate(String strDateBegin,
                                              String strDateEnd) {
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        String strDate = sdf.format(date);
//        // 截取当前时间时分秒
//        int strDateY = Integer.parseInt(strDate.substring(0, 4));
//        int strDateM = Integer.parseInt(strDate.substring(5, 7));
//        int strDateD = Integer.parseInt(strDate.substring(8, 10));
////    System.out.println("111=="+strDateY);
////    System.out.println("111=="+strDateM);
////    System.out.println("111=="+strDateD);
//        // 截取开始时间时分秒
//        int strDateBeginY = Integer.parseInt(strDateBegin.substring(0, 4));
//        int strDateBeginM = Integer.parseInt(strDateBegin.substring(5, 7));
//        int strDateBeginD = Integer.parseInt(strDateBegin.substring(8, 10));
////    System.out.println("222=="+strDateBeginY);
////    System.out.println("222=="+strDateBeginM);
////    System.out.println("222=="+strDateBeginD);
//        // 截取结束时间时分秒
//        int strDateEndY = Integer.parseInt(strDateEnd.substring(0, 4));
//        int strDateEndM = Integer.parseInt(strDateEnd.substring(5, 7));
//        int strDateEndD = Integer.parseInt(strDateEnd.substring(8, 10));
////    System.out.println("333=="+strDateEndY);
////    System.out.println("333=="+strDateEndM);
////    System.out.println("333=="+strDateEndD);
//        if ((strDateY >= strDateBeginY && strDateY <= strDateEndY)) {
//            // 当前时间小时数在开始时间和结束时间小时数之间
//            if (strDateY > strDateBeginY && strDateY < strDateEndY) {
//                return true;
//                // 当前时间小时数等于开始时间小时数，分钟数在开始和结束之间
//            } else if (strDateY == strDateBeginY && strDateM >= strDateBeginM
//                    && strDateM <= strDateEndM) {
//                return true;
//                // 当前时间小时数等于开始时间小时数，分钟数等于开始时间分钟数，秒数在开始和结束之间
//            } else if (strDateY == strDateBeginY && strDateM == strDateBeginM
//                    && strDateD >= strDateBeginD && strDateD <= strDateEndD) {
//                return true;
//            }
//            // 当前时间小时数大等于开始时间小时数，等于结束时间小时数，分钟数小等于结束时间分钟数
//            else if (strDateY >= strDateBeginY && strDateY == strDateEndY
//                    && strDateM <= strDateEndM) {
//                return true;
//                // 当前时间小时数大等于开始时间小时数，等于结束时间小时数，分钟数等于结束时间分钟数，秒数小等于结束时间秒数
//            } else if (strDateY >= strDateBeginY && strDateY == strDateEndY
//                    && strDateM == strDateEndM && strDateD <= strDateEndD) {
//                return true;
//            } else {
//                return false;
//            }
//        } else {
//            return false;
//        }
//        Date BeginDate = toDate(strDateBegin);
//        Date EndDate = toDate(strDateEnd);
        Date sDate = toDate(strDateBegin);
        Date eDate = toDate(strDateEnd);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date nDate = toDate(format.format(new Date()));
        if (nDate.getTime() >= sDate.getTime() && nDate.getTime() <= eDate.getTime()) {
            System.out.print("间范围内..");
            return true;
        } else {
            System.out.print("不在..");
            return false;
        }
    }


    /**
     * 判断时间是否在时间段内  一天天时间滴比较
     *
     * @param strDateBegin 开始时间 00:00:00
     * @param strDateEnd   结束时间 00:05:00
     * @return
     */
    public static boolean isInDate(@NonNull String strDateBegin,
                                   @NonNull String strDateEnd) {
        Calendar ncalendar = Calendar.getInstance();
        int hour = ncalendar.get(Calendar.HOUR_OF_DAY);
        int minute = ncalendar.get(Calendar.MINUTE);
        Log.i("TAG", "当前时间:" + hour + "时" + minute + "分");

        String[] begin = strDateBegin.split(":");
        if (begin == null) return false;
        int strDateBeginH = Integer.parseInt(begin[0]);
        int strDateBeginM = Integer.parseInt(begin[1]);

        String[] end = strDateEnd.split(":");
        if (end == null) return false;
        int strDateEndH = Integer.parseInt(end[0]);
        int strDateEndM = Integer.parseInt(end[1]);

        //如果开始时间和结束时间在同一个小时内，直接比较分钟,分钟数在开始分钟和结束分钟之间，返回true
        if (strDateBeginH == strDateEndH && strDateBeginH == hour && minute >= strDateBeginM && minute <= strDateEndM) {
            return true;
            //小时区间内,直接返回true
        } else if (hour > strDateBeginH && hour < strDateEndH) {
            return true;
            //当前小时数等于开始时间时并小于结束时间。判断分钟是否大于开始分钟数
        } else if (hour == strDateBeginH && hour < strDateEndH && minute >= strDateBeginM) {
            return true;
            //当前小时数等于开始时间时并大于开始时间。判断分钟是否小于结束分钟数
        } else if (hour == strDateEndH && hour > strDateBeginH && minute <= strDateEndM) {
            return true;
            //小时区间外，直接返回false
        } else if (hour < strDateBeginH || hour > strDateEndH) {
            return false;
        } else {
            return false;
        }
    }

    public static void dateTo(String dateStart, String dateStop) {
//        String dateStart = "2016-02-19 09:29:58";
//        String dateStop = "2016-06-20 11:31:48";
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = null;
        Date d2 = null;
        try {
            d1 = format.parse(dateStart);
            d2 = format.parse(dateStop);
            // 毫秒ms
            long diff = d2.getTime() - d1.getTime();
            long diffSeconds = diff / 1000 % 60;
            long diffMinutes = diff / (60 * 1000) % 60;
            long diffHours = diff / (60 * 60 * 1000) % 24;
            long diffDays = diff / (24 * 60 * 60 * 1000);
//            System.out.print("两个时间相差：");
//            System.out.print(diffDays + " 天, ");
//            System.out.print(diffHours + " 小时, ");
//            System.out.print(diffMinutes + " 分钟, ");
            System.out.print(diffSeconds + " 秒.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * password生成方法说明 按照如下步骤计算原文密码串
     * 1)对串进行base64加密
     * 2) 对上一步得到串进行反转（如'1234'反转后是'4321'）
     * 3) 上一步得到的串交换首位和末尾*
     * @param password
     * @return
     */
//    public   static  String  getProtectedPW(String password){
//        String base64Password = Base64.encode(password.getBytes());
//        String reverse = reverse(base64Password);//反转
//        //对上一步得到串进行反转
//        String first = reverse.substring(0, 1); //保存首字符
//        String end = reverse.substring(reverse.length() - 1, reverse.length());//保存尾字符
//        String middle = reverse.substring(1, reverse.length() - 1);//1-30
//        String result = end + middle + first;//拼接
//        return   result;
//    }


    /**
     * 过滤全部字符 只保留数字
     */
    public static String filterChar(String texts) {
        String number = null;
        String regEx = "[0-9]+";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(texts);
        while (m.find()) {
            number = m.group();
        }
        return number;
    }

    /**
     * 从字符串中截取连续6位数字
     * 用于从短信中获取动态密码
     *
     * @param str 短信内容
     * @return 截取得到的6位动态密码
     */
    public static String getDynamicPassword(String str) {
        Pattern continuousNumberPattern = Pattern.compile("[0-9\\.]+");
        Matcher m = continuousNumberPattern.matcher(str);
        String dynamicPassword = "";
        while (m.find()) {
            if (m.group().length() == 6) {
                System.out.print(m.group());
                dynamicPassword = m.group();
            }
        }

        return dynamicPassword;
    }

    /**
     * 格式化银行卡 加*
     * 3749 **** **** 330
     *
     * @param cardNo 银行卡
     * @return 3749 **** **** 330
     */
    public static String formatCard(String cardNo) {
        if (cardNo.length() < 8) {
            return "银行卡号有误";
        }
        String card = "";
        card = cardNo.substring(0, 4) + " **** **** ";
        card += cardNo.substring(cardNo.length() - 4);
        return card;
    }

    /**
     * 隐藏手机中间4位号码
     * 130****0000
     *
     * @param mobile_phone 手机号码
     * @return 130****0000
     */
    public static String hideMobilePhone4(String mobile_phone) {
        if (mobile_phone.length() != 11) {
            return "手机号码不正确";
        }
        return mobile_phone.substring(0, 3) + "****" + mobile_phone.substring(7, 11);
    }


    /**
     * 用户身份证号码的打码隐藏加星号加*
     * <p>18位和非18位身份证处理均可成功处理</p>
     * <p>参数异常直接返回null</p>
     *
     * @param idCardNum 身份证号码
     * @param front     需要显示前几位
     * @param end       需要显示末几位
     * @return 处理完成的身份证
     * <p>
     * formatIDCard("310181198002280637", 6, 4);
     * 310181********0637
     * <p>
     * formatIDCard("310181198002280637", 0, 4);
     * *************0637
     */
    public static String formatIDCard(String idCardNum, int front, int end) {
        //身份证不能为空
        if (TextUtils.isEmpty(idCardNum)) {
            return null;
        }
        //需要截取的长度不能大于身份证号长度
        if ((front + end) > idCardNum.length()) {
            return null;
        }
        //需要截取的不能小于0
        if (front < 0 || end < 0) {
            return null;
        }
        //计算*的数量
        int asteriskCount = idCardNum.length() - (front + end);
        StringBuffer asteriskStr = new StringBuffer();
        for (int i = 0; i < asteriskCount; i++) {
            asteriskStr.append("*");
        }
        String regex = "(\\w{" + String.valueOf(front) + "})(\\w+)(\\w{" + String.valueOf(end) + "})";
        return idCardNum.replaceAll(regex, "$1" + asteriskStr + "$3");
    }


    public static String formatIDCard(String idCardNum) {
        return formatIDCard(idCardNum, 6, 4);
    }
    /**
     * 字符串去空格、冒号和横杠
     */
    public static String formatPhone(String phone) {
        if (!TextUtils.isEmpty(phone)) {
            return phone.replace("[[\\s-:punct:]]", "");
        }
        return "";
    }


}
